/**
 * 矩形的包含判断
 * @param outRect :{x:number,y:number,width:number,height:number}   包含者
 * @param innerRect :{x:number,y:number,width:number,height:number}   被包含者
 * @returns : boolean   表示包含者是否包含被包含者
 *
 * # 注意
 * 包含及相等都属于包含
 */
export function rectIsContain(outRect, innerRect) {
    let left = outRect.x <= innerRect.x;
    let right = outRect.width >= innerRect.width;
    let top = outRect.y <= innerRect.y;
    let bottom = outRect.height <= innerRect.height;

    return (left && right && top && bottom);
}



/**
 * 矩形的相交或包含判断
 * @param rect1 :{x:number,y:number,width:number,height:number}   矩形1
 * @param rect2 :{x:number,y:number,width:number,height:number}   矩形2
 * @returns : boolean   表示矩形1与矩形2是否相交或包含
 *
 * 注意
 * 不包含相切
 */
export function rectIsCrossOrContain(rect1, rect2) {
    let { x: rt1Left, y: rt1Top, width: rt1Width, height: rt1Height } = rect1;
    let rt1Right = rt1Left + rt1Width;
    let rt1Bottom = rt1Top + rt1Height;

    let { x: rt2Left, y: rt2Top, width: rt2Width, height: rt2Height } = rect2;
    let rt2Right = rt2Left + rt2Width;
    let rt2Bottom = rt2Top + rt2Height;

    let max = Math.max;
    let min = Math.min;


    let maxLeft = max(rt1Left, rt2Left);
    let maxTop = max(rt1Top, rt2Top);
    let minRight = min(rt1Right, rt2Right);
    let minBottom = min(rt1Bottom, rt2Bottom);


    let horCross = maxLeft < minRight;
    let verCross = maxTop < minBottom;



    return (horCross && verCross);
}









/**
 * 矩形水平方向上的相交或包含判断
 * @param rect1 :{x:number,y:number,width:number,height:number}   矩形1
 * @param rect2 :{x:number,y:number,width:number,height:number}   矩形2
 * @returns : boolean   表示矩形1与矩形2在水平方向上是否相交或包含
 *
 * 注意
 * 不包含相切
 */
export function rectIsCrossOrContainOnHor(rect1, rect2) {
    let { x: rt1Left, width: rt1Width } = rect1;
    let rt1Right = rt1Left + rt1Width;

    let { x: rt2Left, width: rt2Width } = rect2;
    let rt2Right = rt2Left + rt2Width;

    let maxLeft = Math.max(rt1Left, rt2Left);
    let minRight = Math.min(rt1Right, rt2Right);

    return maxLeft < minRight;
}











/**
 * 矩形垂直方向上的相交或包含判断
 * @param rect1 :{x:number,y:number,width:number,height:number}   矩形1
 * @param rect2 :{x:number,y:number,width:number,height:number}   矩形2
 * @returns : boolean   表示矩形1与矩形2在垂直方向上是否相交或包含
 *
 * 注意
 * 不包含相切
 */
export function rectIsCrossOrContainOnVer(rect1, rect2) {
    let { y: rt1Top, height: rt1Height } = rect1;
    let rt1Bottom = rt1Top + rt1Height;

    let { y: rt2Top, height: rt2Height } = rect2;
    let rt2Bottom = rt2Top + rt2Height;

    let maxTop = Math.max(rt1Top, rt2Top);
    let minBottom = Math.min(rt1Bottom, rt2Bottom);

    return maxTop < minBottom;
}





/**
 * 判断在水平方向上 frontRect 是否在 backRect 的前面，且不相交
 * @param frontRect :{x:number,y:number,width:number,height:number}   前面的矩形
 * @param backRect :{x:number,y:number,width:number,height:number}   后面的矩形
 * @returns : boolean   表示在水平方向上 frontRect 是否在 backRect 的前面，且不相交；
 *
 * 注意
 * 包含相切
 */
export function rectIsInFrontOnHor(frontRect, backRect) {
    let frontRight = frontRect.x + frontRect.width;
    return frontRight <= backRect.x;
}



/**
 * 判断在垂直方向上 frontRect 是否在 backRect 的前面，且不相交
 * @param frontRect :{x:number,y:number,width:number,height:number}   前面的矩形
 * @param backRect :{x:number,y:number,width:number,height:number}   后面的矩形
 * @returns : boolean   表示在垂直方向上 frontRect 是否在 backRect 的前面，且不相交；
 *
 * 注意
 * 包含相切
 */
export function rectIsInFrontOnVer(frontRect, backRect) {
    let frontBottom = frontRect.y + frontRect.height;
    return frontBottom <= backRect.y;
}









/**
 * 矩形的相交判断
 * @param rect1 :{x:number,y:number,width:number,height:number}   矩形1
 * @param rect2 :{x:number,y:number,width:number,height:number}   矩形2
 * @returns : boolean   表示矩形1与矩形2是否相交
 *
 * # 注意
 * 包含不属于相交
 */
export function rectIsCross(rect1, rect2) {
    let crossOrContain = rectIsCrossOrContain(rect1, rect2);
    let contain2 = rectIsContain(rect1, rect2);
    let contain1 = rectIsContain(rect2, rect1);

    return (crossOrContain && !contain2 && !contain1);
}




/**
 * 矩形的相切
 * @param rect1 :{x:number,y:number,width:number,height:number}   矩形1
 * @param rect2 :{x:number,y:number,width:number,height:number}   矩形2
 * @returns : boolean   表示矩形1与矩形2是否相切
 *
 */
export function rectIstTangent(rect1, rect2) {
    let { x: rt1Left, y: rt1Top, width: rt1Width, height: rt1Height } = rect1;
    let rt1Right = rt1Left + rt1Width;
    let rt1Bottom = rt1Top + rt1Height;

    let { x: rt2Left, y: rt2Top, width: rt2Width, height: rt2Height } = rect2;
    let rt2Right = rt2Left + rt2Width;
    let rt2Bottom = rt2Top + rt2Height;



    let isCrossOrContain = rectIsCrossOrContain(rect1, rect2);

    //判断单边是否相切
    let rt1L = rt1Right === rt2Left;
    let rt1R = rt1Left === rt2Right;
    let rt1T = rt1Bottom === rt2Top;
    let rt1B = rt1Top === rt2Bottom;

    //判断是否有相切的边
    let haveTangent = rt1L || rt1R || rt1T || rt1B;


    return (!isCrossOrContain && haveTangent);
}










/**
 * 判断点是否在矩形内
 * @param point :{x:number,y:number}   点
 * @param rect :{x:number,y:number,width:number,height:number}   矩形
 * @returns : boolean
 *
 * # 注意
 * 不包含 点 在 矩形边上的情况
 */
export function pointInRect(point, rect) {
    let { x: left, y: top, width, height } = rect;
    let right = left + width;
    let bottom = top + height;

    let { x: px, y: py } = point;

    let pL = left < px;
    let pR = px < right;
    let pT = top < py;
    let pB = py < bottom;

    return (pL && pR && pT && pB);
}



/**
 * 判断点是否在矩形上
 * @param point :{x:number,y:number}   点
 * @param rect :{x:number,y:number,width:number,height:number}   矩形
 * @returns : boolean
 *
 * # 注意
 * 包含 点 在 矩形边上的情况
 */
export function pointOnRect(point, rect) {
    let { x: left, y: top, width, height } = rect;
    let right = left + width;
    let bottom = top + height;

    let { x: px, y: py } = point;

    let pL = left <= px;
    let pR = px <= right;
    let pT = top <= py;
    let pB = py <= bottom;

    return (pL && pR && pT && pB);
}




/**
 * 判断点是否在矩形的边框上
 * @param point :{x:number,y:number}   点
 * @param rect :{x:number,y:number,width:number,height:number}   矩形
 * @returns : boolean   表示是否在矩形的边框上
 *
 */
export function pointOnRectBorder(point, rect) {
    let onRect = pointOnRect(point, rect);
    let inRect = pointInRect(point, rect);

    return (!inRect && onRect);
}





/**
 * 扩展矩形
 * @param rect :{x:number,y:number,width:number,height:number} 原矩形
 * @param horExtendRadius : number 水平扩展半径
 * @param verExtendRadius : number 垂直扩展半径
 * @returns : {x: number, y: number, width: number, height: number}  扩展后的矩形
 */
export function extendRect(rect, horExtendRadius, verExtendRadius) {
    let { x, y, width, height } = rect;
    x = x - horExtendRadius;
    y = y - verExtendRadius;
    width = width + horExtendRadius * 2;
    height = height + verExtendRadius * 2;
    return { x, y, width, height };
}
